home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * Newton model building routines
- * HISTORICAL NOTE: a Newton model used to be called a ``jello'', hence
- * some of the `j's that appear throughout the code ...
- * Yossi Friedman, July 1988
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- #include <string.h>
- #include <gl.h>
-
- #include "config.h"
- #include "newton.h"
-
-
- extern char *cwd();
-
-
- static char *model_fnames[MAX_MODELS], **end_model_fnames;
-
-
-
- #define LINELEN 10240
-
-
- static Atom *new_atom(float, float, float);
- static Spring *new_spring(float, Atom *, Atom *);
- static Surf *new_surf(int, Atom **);
-
-
-
- initialize_models()
- {
- FILE *fp;
- char line[LINELEN];
- char *p, *q, *r;
- int len;
- int n;
-
- /*
- * grab the list of names from model catalog
- */
-
- if (strcmp(model_catalog, "-") == 0)
- fp = stdin;
- else {
- fp = fopen(model_catalog, "r");
- if (fp == NULL) {
- fprintf(stderr, "newton: Could not open %s/%s\n", cwd(),
- model_catalog);
- my_exit(1);
- }
- }
-
- end_model_names = model_names;
- end_model_fnames = model_fnames;
-
- n = 0;
- while(fgets(line, LINELEN, fp) != NULL) {
- for (p = line; *p && (*p != '\n') && (*p != '#');) {
-
- /* skip white space */
- if (isspace(*p)) {
- p++;
- continue;
- }
-
- /* make sure we have space */
- if (++n >= MAX_MODELS) {
- fprintf(stderr, "newton: too many models in the catalog. Max is %d\n", MAX_MODELS);
- my_exit(1);
- }
-
- /* found a beginning of a name. Figure out where it ends */
- for (q = p+1; *q && (*q != '\n') && (*q != '#'); q++)
- if (isspace(*q))
- break;
-
- len = q - p;
- p[len] = 0;
-
- *end_model_fnames = (char *) malloc(1 + len);
- if (*end_model_fnames == NULL) {
- fprintf(stderr, "newton: Could not malloc\n");
- my_exit(1);
- }
- strcpy(*end_model_fnames++, p);
-
- if (p[len-1] == 'j' && p[len-2] == '.')
- p[len-2] = '\0';
- if ((r = strrchr(p, '/')) != NULL)
- p = r + 1;
- len = strlen(p);
- *end_model_names = (char *) malloc(1 + len);
- if (*end_model_names == NULL) {
- fprintf(stderr, "newton: Could not malloc\n");
- my_exit(1);
- }
- strcpy(*end_model_names++, p);
-
- /* advance to the next name */
- p = q+1;
- }
- }
-
- if (end_model_names - model_names == 0) {
- fprintf(stderr, "newton: No model description files\n");
- my_exit(1);
- }
-
- /* by default, build the first model on the list */
- model_index = 0;
- build_model(1);
- }
-
-
- build_model(int from_scratch)
- {
- char *model_fname;
- FILE *fp;
- char line[LINELEN];
- char *p;
- int q;
-
- int from, to, v, n;
- float old_max_k, x, y, z, k, f;
- Atom *surf_buf[MAX_SURF_N];
-
- free_atoms();
- free_springs();
- free_surfs();
-
- model_fname = model_fnames[model_index];
- fp = fopen(model_fname, "r");
- if (fp == NULL) {
- fprintf(stderr, "newton: Could not open ");
- if (model_fname[0] != '/')
- fprintf(stderr, "%s/", cwd());
- fprintf(stderr, "%s\n", model_fname);
- my_exit(1);
- }
-
- if (from_scratch) {
-
- /* set the default material properites for the model */
- model_material_size = default_model_material_size;
- memcpy(model_material, default_model_material,
- model_material_size * sizeof(float));
-
- /* set the default draw functions for the model */
- draw_model = DRAW_MODEL_DEFAULT;
- springs_too = SPRINGS_TOO_DEFAULT;
- alpha_blended = ALPHA_BLENDED_DEFAULT;
- }
-
- old_max_k = max_k;
- max_k = -1500.; /* minus infinity */
-
- while (fgets(line, LINELEN, fp) != NULL)
- switch (line[0]) {
- case '\n':
- case '#':
- continue;
-
- case 'a':
- sscanf(line + 1, "%f %f %f", &x, &y, &z);
- new_atom(x, y, z);
- break;
-
- case 'c':
- sscanf(line + 1, "%f %d %d", &k, &from, &to);
- (void) new_spring(k, &model_atoms[from], &model_atoms[to]);
- if (max_k < k)
- max_k = k;
- break;
-
- case 's':
- p = line + 1;
- for (n = 0; sscanf(p, "%d%n", &v, &q) == 1; p += q) {
- if (n == MAX_SURF_N) {
- fprintf(stderr, "newton: %s: Surface too big\n", model_fname);
- my_exit(1);
- }
- surf_buf[n++] = &model_atoms[v];
- }
- (void) new_surf(n, surf_buf);
- break;
-
- case 'M':
- p = line + 1;
- for (n = 0; sscanf(p, "%f%n", &f, &q) == 1; p += q) {
- if (n == MAX_LIGHTING_SIZE) {
- fprintf(stderr, "newton: %s: Material too big\n", model_fname);
- my_exit(1);
- }
- model_material[n++] = f;
- }
- model_material_size = n;
- break;
-
- case 'S':
- draw_model = draw_smooth_surfs;
- break;
-
- case 'F':
- draw_model = draw_flat_surfs;
- break;
-
- case 'B':
- if (from_scratch && (mode != COLOR_MAP)) {
- mode = COLOR_MAP;
- cmode();
- gconfig();
- }
- break;
-
- default:
- fprintf(stderr, "newton: %s: Syntax error\n", model_fname);
- my_exit(1);
- }
-
- fclose(fp);
-
- #ifdef MP
-
- {
- /*
- * divide the atoms, springs and surfs lists
- */
- int i;
- int n_atoms = (end_model_atoms TOTAL - model_atoms) / nproc;
- int n_springs = (end_model_springs TOTAL - model_springs) / nproc;
- int n_surfs = (end_model_surfs TOTAL - model_surfs) / nproc;
-
- end_model_atoms MASTER = model_atoms + n_atoms;
- end_model_springs MASTER = model_springs + n_springs;
- end_model_surfs MASTER = model_surfs + n_surfs;
-
- for (i = 1; i < nproc - 1; i++) {
- end_model_atoms[i] = end_model_atoms[i-1] + n_atoms;
- end_model_springs[i] = end_model_springs[i-1] + n_springs;
- end_model_surfs[i] = end_model_surfs[i-1] + n_surfs;
- }
- }
-
- #endif /* MP */
-
- /*
- * this is necessary in order to set dt and redraw the K slider
- */
- if (from_scratch)
-
- #if ECLIPSE || CLOVER1 /* the slow machines */
- set_default_k(max_k / 2.0);
- #else /* ECLIPSE || CLOVER1 */
- set_default_k(max_k);
- #endif /* ECLIPSE || CLOVER1 */
-
- else
- set_k(old_max_k);
-
- /*
- * set the model material
- */
- if (from_scratch) {
-
- #ifndef HAS_BLENDING
-
- /* kludge to avoid crashes due to alpha blending */
- if (model_material[0] == (float)ALPHA)
- lmdef(DEFMATERIAL,
- MODEL_MATERIAL_INDEX,
- model_material_size - 2,
- model_material + 2);
- else
-
- #endif /* HAS_BLENDING */
-
- lmdef(DEFMATERIAL,
- MODEL_MATERIAL_INDEX,
- model_material_size,
- model_material);
- }
- }
-
-
- /*
- * rotate the model in the ROOM coordinate system
- * around a VIEWING axis
- */
- rotate_model(Angle alpha, char axis)
- {
- /*
- * the formula is:
- * v R = v M rot M_inv,
- * where rot is the rotation matrix (in the viewing system) around the
- * viewing axis.
- */
- pushmatrix();
- loadmatrix(M_inv);
- rotate(alpha, axis);
- multmatrix(M);
- getmatrix(R);
- popmatrix();
-
- SLAVE_FUNC(DO_ROTATE_MODEL);
- do_rotate_model(model_atoms, end_model_atoms MASTER);
- WAIT_FOR_SLAVE();
- }
-
- do_rotate_model(Atom *start, Atom *finish)
- {
- Atom *ap;
- float ov[3], *v;
-
- for (ap = start; ap < finish; ap++) {
- v = ap->pos;
- ov[X] = v[X]; ov[Y] = v[Y]; ov[Z] = v[Z];
- apply(v, ov, R);
- }
- }
-
-
- /*
- * Data Structure Stuff
- */
-
- free_atoms()
- {
-
- #ifdef MP
-
- {
- int i;
-
- for (i = 0; i < nproc; i++)
- end_model_atoms[i] = model_atoms;
- }
-
- #else /* MP */
-
- end_model_atoms = model_atoms;
-
- #endif /* MP */
-
- }
-
- static Atom *
- new_atom(float x, float y, float z)
- {
- if (end_model_atoms TOTAL == model_atoms + MAX_ATOMS) {
- fprintf(stderr, "newton: %s: Too many atoms\n", model_names[model_index]);
- my_exit(1);
- }
-
- end_model_atoms TOTAL ->pos[X] = x;
- end_model_atoms TOTAL ->pos[Y] = y;
- end_model_atoms TOTAL ->pos[Z] = z;
-
- end_model_atoms TOTAL ->vel[X] = 0.0;
- end_model_atoms TOTAL ->vel[Y] = 0.0;
- end_model_atoms TOTAL ->vel[Z] = 0.0;
-
- #ifdef MP
-
- {
- int i;
-
- for (i = 0; i < nproc; i++)
- end_model_atoms TOTAL ->acc[i][X] =
- end_model_atoms TOTAL ->acc[i][Y] =
- end_model_atoms TOTAL ->acc[i][Z] = 0.;
- }
-
- #else /* MP */
-
- end_model_atoms TOTAL ->acc[X] =
- end_model_atoms TOTAL ->acc[Y] =
- end_model_atoms TOTAL ->acc[Z] = 0.0;
-
- #endif /* MP */
-
- return(end_model_atoms TOTAL ++);
- }
-
-
- free_springs()
- {
-
- #ifdef MP
-
- {
- int i;
-
- for (i = 0; i < nproc; i++)
- end_model_springs[i] = model_springs;
- }
-
- #else /* MP */
-
- end_model_springs = model_springs;
-
- #endif /* MP */
-
- }
-
- static Spring *
- new_spring(float k, Atom *a1, Atom *a2)
- {
- float r0[3];
-
- if (end_model_springs TOTAL == model_springs + MAX_SPRING) {
- fprintf(stderr, "newton: %s: Too many springs\n", model_names[model_index]);
- my_exit(1);
- }
-
- end_model_springs TOTAL ->k = k;
- end_model_springs TOTAL ->from = a1;
- end_model_springs TOTAL ->to = a2;
-
- vec_op(r0, a1->pos, -, a2->pos);
- end_model_springs TOTAL ->r0 = sqrt(r0[X]*r0[X] + r0[Y]*r0[Y] + r0[Z]*r0[Z]);
-
- return(end_model_springs TOTAL ++);
- }
-
-
- free_surfs()
- {
- Surf *sp;
-
- for (sp = model_surfs; sp < end_model_surfs TOTAL; sp++) {
- free(sp->vert);
- free(sp->norm);
- }
-
- #ifdef MP
-
- {
- int i;
-
- for (i = 0; i < nproc; i++)
- end_model_surfs[i] = model_surfs;
- }
-
- #else /* MP */
-
- end_model_surfs = model_surfs;
-
- #endif /* MP */
-
- }
-
- static Surf *
- new_surf(int n, Atom **vert)
- {
- Atom **ap;
-
- if (end_model_surfs TOTAL == model_surfs + MAX_SURF) {
- fprintf(stderr, "newton: %s: Too many surfs\n", model_names[model_index]);
- my_exit(1);
- }
-
- if (n < 3) {
- fprintf(stderr, "newton: %s: Surf too small\n", model_names[model_index]);
- my_exit(1);
- }
-
- end_model_surfs TOTAL ->n = n;
- end_model_surfs TOTAL ->vert = (Atom **) malloc(n * sizeof(Atom *));
- if (end_model_surfs TOTAL ->vert == NULL) {
- fprintf(stderr, "newton: %s: Could not malloc\n", model_names[model_index]);
- my_exit(1);
- }
- for (ap = end_model_surfs TOTAL ->vert; n--; *ap++ = *vert++)
- ;
- end_model_surfs TOTAL ->norm = (float *) malloc(end_model_surfs TOTAL ->n * 4 * sizeof(float));
- if (end_model_surfs TOTAL ->norm == NULL) {
- fprintf(stderr, "newton: %s: Could not malloc\n", model_names[model_index]);
- my_exit(1);
- }
-
- return(end_model_surfs TOTAL ++);
- }
-